本篇會介紹如何在 TypeScript 中使用 Class,但是可別搞混了哦!TypeScript 的 Class 和 JavaScript 的 Class 一點關係都沒有,雖然最後還是會編譯成 JavaScript 啦,不過編譯過後也不會是 Class,而是 Prototype 就是了,如果對 JavaScript 的 Class 還不熟的話建議可以先讀過「JavaScript | ES6 中最容易誤會的語法糖 Class - 基本用法」這篇,而在 TypeScript 的 Class 也多了一些 modifiers,例如 public
、private
和 protected
本篇都會簡單介紹。
假設我們有張製作汽車的設計圖,那只要依照這張設計圖製作,所產生出來的車都會擁有相同的特型。
承上方的例子,在目錄下新增 Car.ts 檔案,並其中建立一個 Car
的 Class,在 Class 裡會描述 Instance 會有哪些特性:
class Car {
public model: string = 'GQSM-X';
public getDescription(): string {
return `型號是:${this.model}`;
}
}
遵從 Class 的淺規則,讓 Car
的字首 C 大寫,Car
內有兩個 Properties 特性,model
記錄著車子的型號,另一個是 getDescription
會回傳該車子的敘述。
使用 new
就能以 Class 創建 Instance:
const car1 = new Car();
console.log(car1.getDescription()); // 型號是:GQSM-X
不論創建幾個物件,只要是以 Car
Class 建立的 instance 都會得到與上方相同的結果。
如果要執行看結果,可以在終端機中輸入 tsc Car.ts
編譯,接著使用 node Car.js
執行:
Constructor 會在 Class 建立 Instance 時執行,且如果 Class 在建立 Instance 有傳入任何參數的話,也都會由 Constructor 接收,例如要為 Car
增加顏色,就可以使用 Constructro 接收顏色進行指定:
class Car {
public model: string = 'GQSM-X';
public color: string;
constructor(color: string) {
this.color = color;
}
public getDescription(): string {
return `型號是:${this.model}(${this.color})`;
}
}
這麼一來便能在建立 Instance 時傳入顏色,並在 Constructor 中將顏色指定給自己的 Property color
:
const redCar = new Car('Red');
const blueCar = new Car('Blue');
console.log(redCar.getDescription());
// 型號是:GQSM-X(Red)
console.log(blueCar.getDescription());
// 型號是:GQSM-X(Blue)
到目前為止,Car
內所有的屬性都是 public
,如果沒有特別指定也會是 Public
,也就是公開的,所以我們可以直接從 Instance 中取出 Property 的值,例如 color
或是 model
:
console.log(redCar.model) //GQSM-X
console.log(redCar.color) //Red
如果在 Class 的 Property 前加上 private
,那 Property 就會變成私有的,無法直接以上述的方式取得值,下方就試著把 Car
內的 model
變成私有的:
class Car {
private model: string = 'GQSM-X';
/* 其餘省略 */
}
model
變成私有後,如果還要試圖直接從物件中取得,那就會出現警告:
如果要為當前的 Car
為基底,再建立另一個 Class,就能讓新的 Class 使用 Inheritance 繼承 Car
的所有 Properties,而 Inheritance 的操作也很容易,只需要在新的 Class 後使用 extends
並加上要繼承的 Class 就好,例如:
class Car {
private model: string = 'GQSM-X';
public color: string;
constructor(color: string) {
this.color = color;
}
public getDescription(): string {
return `型號是:${this.model}(${this.color})`;
}
}
// CarII 繼承了 Car
class CarII extends Car {
public getDescription(): string {
return `${super.getDescription()}(II)`;
}
}
這裡需要注意,雖然 CarII
沒有 Constructor,但是因為它繼承了 Car
,所以還是需要在建構 Instance 的時候傳進參數作為 color
,而在 getDescription
內使用的 super
就代表著父類別,也就是執行了父類別的 getDescription
。
除此之外,如果父類別的 Constructor 需要接收多個值,那在子類別的 Constructor 中,也可以用 super
將值傳送給父類別的 Constructor,但如果父類別只需要接收一個參數,那就不需要再使用 super
,TypeScript 會自動將它送給父類別。
上方的執行結果如下:
const redCarII = new CarII('Red');
console.log(redCarII.getDescription());;
// 執行結果:
// 型號是:GQSM-X(Red)(II)
Protected 和 Private 很類似,差別在 Private 是私有的屬性,因此除了本身的類別外,便無法偷看裡面是什麼,否則就會出錯,子類別也不例外,但是如果 Protected,就還可以在子類別中讀取:
class Car {
// 將 model 改為 protected
protected model: string = 'GQSM-X';
/* 其餘省略 */
}
// CarII 繼承了 Car
class CarII extends Car {
public getModel(): string {
// 直接使用父類別的 protected
return this.model;
}
public getDescription(): string {
return `${super.getDescription()}(II)`;
}
}
console.log(redCarII.getModel());
// GQSM-X
這裡特別說明一下,關於獲取 model
這個屬性為什麼是使用 this
而不是 super
,
model
則是實現於 Instance,super
正是指向父類別的 Prototype,而不是 Instance,因此在 Prototype 中找不到 model
時就會發生警告,另一方面的 this
就是指本身被創建出來的 Instance,既然是 Instance 那當然就找得到 model
。
正常來說,Class 都要被創建為 Instance 後,才有辦法使用在 Class 內所描述的方法,但只要使用 static
,就能直接在 Class 上呼叫此方法:
// CarII 繼承了 Car
class CarII extends Car {
static getComment(): string {
return '我是二代車';
}
/* 其餘省略 */
}
// 直接呼叫靜態 Method
console.log(CarII.getComment());
使用 static
時需要注意一下,因為不需要建立 Instance 就可以使用,所以在 static
內是不能使用 this
的,因為根本就沒有 Instance。
本文的範例程式碼會提供在 GitHub 上,歡迎各位參考:)
本章介紹了在 TypeScript 中使用 Class 的用法,雖然有些語法還沒支援,但是看起來和 JavaScript 的 ES6 還挺相似的,下一章會接著說明關於 Interface 接口,在物件導向的編程中,Interface 可是佔了很重要的部分!
如果文章中有任何問題,或是不理解的地方,都可以留言告訴我!謝謝大家!
const redCarII = new CarII('Red');
redCarII.getDescription();
改成
const redCarII = new CarII('Red');
console.log(redCarII.getDescription());
其實我一直都不是很理解OOP的結構
但是這篇真的讓我有多了解一點OOP
甚麼時候該用super
甚麼時候該用this
都有很好的解釋
感謝你!我保證今年不會再寫 React 的系列文了!
哈哈 我現在半隻腳踏入TypeScript
也是要感謝你的文章
期待你今年鐵人賽
PS 我私心希望會有react刻畫面教學
沒有也沒關係~我會再爬文學的